//
//  School.m
//  SSL_Runtime_Learn
//
//  Created by SSLong on 2018/2/12.
//  Copyright © 2018年 sunshilong. All rights reserved.
//

#import "School.h"
#import "Teacher.h"
#import <objc/runtime.h>
@implementation School
-(void)RecruitmentTeacher{
    NSLog(@"recruitment a teacher");
}
#pragma mark --- 1
/*
 如果当前对象调用了一个不存在的方法
 Runtime会调用resolveInstanceMethod:来进行动态方法解析
 我们需要用class_addMethod函数完成向特定类添加特定方法实现的操作
 返回NO，则进入下一步forwardingTargetForSelector:
 */
+(BOOL)resolveInstanceMethod:(SEL)sel{
    
#if 0
    return NO;
#else
    class_addMethod(self, sel, class_getMethodImplementation(self, sel_registerName("RecruitmentTeacher")), "v@:");
    return [super resolveInstanceMethod:sel];
#endif
}
#pragma mark ---2
/*
 在消息转发机制执行前，Runtime 系统会再给我们一次 “重定向” 的机会
 通过重载forwardingTargetForSelector:方法来替换消息的接受者为其他对象
 返回nil则进步下一步forwardInvocation:
 */
-(id)forwardingTargetForSelector:(SEL)aSelector{
    
#if 0
    return nil;
#else
    //    return nil;
    return [[Teacher alloc] init];//找到可以实现方法的对象，进行替换
#endif
}
#pragma mark ---3
/*
 进行方法签名，
 返回nil，表示不做签名处理，
 若返回方法签名，进入下一步，消息转发
 */
-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{

    //    return nil;
    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
#pragma mark ---4
/*
 消息转发
 可以做很多操作，修改实现方法，修改相应对象
 */
-(void)forwardInvocation:(NSInvocation *)anInvocation{
    
    return [anInvocation invokeWithTarget:[[Teacher alloc] init]];//修改相应对象
}

@end
